﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using SerialPort_URAT.Properties;
using System.Threading;
using System.IO;
using System.IO.Ports;

using System.Management;

using System.Reflection;
using System.Diagnostics;
//using Microsoft.DirectX;
//using Microsoft.DirectX.Direct3D;

namespace SerialPort_URAT
{
    #region Public Enumerations
    public enum connection { Half_Duplex, Full_Duplex };
    public enum MonitorShow { None, OneWireShowing, CommandShowing };
    public enum DataMode { Text, Hex };
    public enum LogMsgType { Incoming, Outgoing, Normal, Warning, Error, Test };
    #endregion

    
    public partial class SerialPortForm : Form
    {
        #region Local Variables

        private Settings settings = Settings.Default;
        // Various colors for logging info
        private Color[] LogMsgTypeColor = { Color.Blue, Color.Green, Color.Black, Color.Orange, Color.Red, Color.Pink };

        // The main control for communicating through the RS-232 port
        private SerialPort gSerialComPort = new SerialPort();

        List<Byte> ReceivedComPortBytesList = new List<Byte>();
        List<Byte> TrasnmitComPortBytesList = new List<Byte>();

        LEV_ST_Monitor_Form ST_Monitor_Form;

        const int Max_Showing_Message_Lines = 60;
        #endregion

        string Data_Log_Default_Folder = "DP_LEV_Monitor_Record";
        public string Data_Log_Directory = "";

        string FA_Tool_Default_Director = @"C:\DP_FATOOL\recode_data";
        string FA_Tool_Log_Detection_Tick = "system data";
        StreamReader FA_Tool_DataLogReader;

        public SerialPortForm()
        {
            // Load user settings
            settings.Reload();

            InitializeComponent();
            InitializeControlValues();
            StartPosition = FormStartPosition.CenterScreen;
            // When data is recieved through the port, call this method
            //gSerialComPort.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
            EnableControls();
            //this.Text = this.Text + "( Release Version : " + Assembly.GetEntryAssembly().GetName().Version.ToString() + " )";
            //Assembly assembly = Assembly.GetExecutingAssembly();
            //FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
            //this.Text = this.Text + "( Release Version : " + fvi.FileVersion + " )";
            //this.Text = this.Text + "( Release Version : " + fvi.ProductVersion + " )";
            if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
            {
                this.Text = this.Text + "( Release Version : " + System.Deployment.Application.ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString() + " )";
            }

        }

        /// <summary> Save the user's settings. </summary>
        private void SaveSettings()
        {
            settings.BaudRate = int.Parse(cmbBaudRate.Text);
            settings.DataBits = int.Parse(cmbDataBits.Text);
            settings.DataMode = CurrentDataMode;
            settings.Parity = (Parity)Enum.Parse(typeof(Parity), cmbParity.Text);
            settings.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cmbStopBits.Text);
            settings.PortName = GetSelectedComPortName();
            settings.connection = CurrentDataConnection;
            settings.MonitorShowing = CurrentMonitorShowingSelect;

            settings.Save();
        }

        /// <summary> Populate the form's controls with default settings. </summary>
        private void InitializeControlValues()
        {
            cmbParity.Items.Clear(); cmbParity.Items.AddRange(Enum.GetNames(typeof(Parity)));
            cmbStopBits.Items.Clear(); cmbStopBits.Items.AddRange(Enum.GetNames(typeof(StopBits)));
            cmbStopBits.Text = settings.StopBits.ToString();
            cmbDataBits.Text = settings.DataBits.ToString();
            cmbParity.Text = settings.Parity.ToString();
            cmbBaudRate.Text = settings.BaudRate.ToString();
            CurrentDataMode = settings.DataMode;
            CurrentDataConnection = settings.connection;

            CurrentMonitorShowingSelect = settings.MonitorShowing;
			// Order the serial port names in numberic order (if possible)
			//int num;
            //string [] orderPortArray = SerialPort.GetPortNames().OrderBy(a => a.Length > 3 && int.TryParse(a.Substring(3), out num) ? num : 0).ToArray();

            string[] PortArray = UpdatedComPortAndDescription();
            cmbPortName.Items.Clear();
            cmbPortName.Items.AddRange(PortArray);

            bool cmbPortNameSelected = false;
            for (int i = 0; i < PortArray.GetLength(0); i++)
            {
                cmbPortName.SelectedIndex = i;
                if (cmbPortName.Text.Contains(settings.PortName))
                {
                    cmbPortNameSelected = true;
                    break;
                }
            }

            // If it is still avalible, select the last com port used
            if (cmbPortNameSelected)
            {
            }
            else if (cmbPortName.Items.Count > 0)
            {
                //select last item
                cmbPortName.SelectedIndex = cmbPortName.Items.Count - 1;    
            }
            else
            {
                DialogResult result = MessageBox.Show("There are no COM Ports detected on this computer.\nPlease install a COM Port and restart this app.\n Do you want to CLOSE this program?", "Confirmation", MessageBoxButtons.YesNoCancel);
                if(result == DialogResult.Yes){
                    this.Close();
                }
                else if (result == DialogResult.No)
                {
                }
                else
                {
                }
            }
        }
        /// <summary> Enable/disable controls based on the app's current state. </summary>
        private void EnableControls()
        {
            // Enable/disable controls based on whether the port is open or not
            gbPortSettings.Enabled = !gSerialComPort.IsOpen;
            gbMode.Enabled = !gSerialComPort.IsOpen;
            Connection_groupBox.Enabled = !gSerialComPort.IsOpen;
            MonitorShowing_groupBox.Enabled  = !gSerialComPort.IsOpen;
            SendingData_groupBox.Enabled  = gSerialComPort.IsOpen;

            Log_Name_textBox.Enabled = false;


        }
        private string[] UpdatedComPortAndDescription_()
        {
            string[] comport = SerialPort.GetPortNames();


            // Query for descending sort.
            IEnumerable<string> sortDescendingQuery =
                from dOrder in comport
                orderby dOrder //"ascending" is default
                //orderby dOrder descending
                select dOrder;

            return sortDescendingQuery.ToArray<string>();
        }
        private string[] UpdatedComPortAndDescription()
        {
            bool find_com_Port = false;

            string[] comport = new string[] { "" };
            try
            {
                comport = SerialPort.GetPortNames();
                find_com_Port = true;
            }
            catch (Exception ecp)
            {
                find_com_Port = false;
            }
            if (!find_com_Port)
            {
                return new string[]{""};
            }

            try
            {
                ManagementObjectSearcher searcher =
                    new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_PnPEntity");// WHERE ConfigManagerErrorCode = 0");
                //new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM WIN32_SerialPort");
                /*
                foreach (ManagementObject queryObj in searcher.Get())
                {
                    //if (queryObj["Caption"].ToString().Contains("(COM"))
                    //if (queryObj["Caption"].ToString().Contains("COM"))
                    //if (queryObj["Caption"].ToString().StartsWith("serial port"))
                    if (queryObj["Caption"].ToString().Contains("serial port"))
                    {
                        //Console.WriteLine("serial port : {0}", queryObj["Caption"]);  //result : Description
                        //Console.WriteLine("serial port : {0}", queryObj["DeviceID"]); // result : COM20
                    }
                }
                */

                for (int i = 0; i < comport.GetLength(0); i++)
                {
                    string str1 = "";
                    foreach (ManagementObject queryObj in searcher.Get())
                    {
                        if (queryObj["Caption"].ToString().Contains(comport[i]))
                        {
                            str1 += queryObj["Caption"].ToString();
                        }

                        /*
                        if (queryObj["DeviceID"].ToString().StartsWith(comport[i]))
                        {
                            str1 = queryObj["Caption"].ToString();
                            str1 = queryObj["Name"].ToString();
                        }*/
                    }//foreach (ManagementObject queryObj in searcher.Get())
                    comport[i] = comport[i] + ": " + str1;
                }
            }
            catch (Exception exx)
            {
                //MessageBox.Show(exx.Message);
                Log(LogMsgType.Error, " " + exx.Message + Environment.NewLine);
            }

            // Query for descending sort.
            IEnumerable<string> sortDescendingQuery =
                from dOrder in comport
                orderby dOrder //"ascending" is default
                //orderby dOrder descending
                select dOrder;

            return sortDescendingQuery.ToArray<string>();
        }
        #region Local Properties
        private string GetSelectedComPortName()
        {
            return (string)cmbPortName.Text.Split(new char[] { ':' }).GetValue(0);
        }
        private DataMode CurrentDataMode
        {
            get
            {
                if (rbHex.Checked) return DataMode.Hex;
                else return DataMode.Text;
            }
            set
            {
                if (value == DataMode.Text) rbText.Checked = true;
                else rbHex.Checked = true;
            }
        }
        private connection CurrentDataConnection
        {
            get
            {
                if (Half_Duplex_radioButton.Checked) return connection.Half_Duplex;
                else return connection.Full_Duplex;
            }
            set
            {
                if (value == connection.Half_Duplex) Half_Duplex_radioButton.Checked = true;
                else Full_Duplex_radioButton.Checked = true;
            }
        }
        private MonitorShow CurrentMonitorShowingSelect
        {
            get
            {
                if (NoneMonitorForm_radioButton.Checked) return MonitorShow.None;
                else if (OneWireShowMonitor_radioButton.Checked) return MonitorShow.OneWireShowing;
                else return MonitorShow.CommandShowing;
            }
            set
            {
                if (value == MonitorShow.None) NoneMonitorForm_radioButton.Checked = true;
                else if (value == MonitorShow.OneWireShowing) OneWireShowMonitor_radioButton.Checked = true;
                else CommandShowMonitor_radioButton.Checked = true;
            }
        }

        /// <summary> Convert a string of hex digits (ex: E4 CA B2) to a byte array. </summary>
        /// <param name="s"> The string containing the hex digits (with or without spaces). </param>
        /// <returns> Returns an array of bytes. </returns>
        private byte[] HexStringToByteArray(string s)
        {
            s = s.Replace(" ", "");
            if ((s.Length % 2) > 0)
            {
                return new byte[1];
            }
            byte[] buffer = new byte[(s.Length / 2)];
            for (int i = 0; i < s.Length; i += 2)
                buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
            return buffer;
        }

        /// <summary> Converts an array of bytes into a formatted string of hex digits (ex: E4 CA B2)</summary>
        /// <param name="data"> The array of bytes to be translated into a string of hex digits. </param>
        /// <returns> Returns a well formatted string of hex digits with spacing. </returns>
        private string ByteArrayToHexString(byte[] data)
        {
            StringBuilder sb = new StringBuilder(data.Length * 3);
            foreach (byte b in data)
                sb.Append(Convert.ToString(b, 16).PadLeft(2, '0').PadRight(3, ' '));
            return sb.ToString().ToUpper();
        }
        #endregion


        private void AboutLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            // Show the user the about dialog
            (new About()).ShowDialog(this);
            
        }
        //控制UI 更新
        private delegate void myUICallBack(string myStr, Control ctl);
        private void myUI(string myStr, Control ctl)
        {
            if (this.InvokeRequired)
            {
                myUICallBack myUpdate = new myUICallBack(myUI);
                this.Invoke(myUpdate, myStr, ctl);
            }
            else
            {
                ctl.Text = myStr;
            }
        }
        /// <summary> Log data to the terminal window. </summary>
        /// <param name="msgtype"> The type of message to be written. </param>
        /// <param name="msg"> The string containing the message to be shown. </param>
        private void Log_Clear()
        {
            richTextBox1.Invoke(new EventHandler(delegate
            {
                richTextBox1.Clear ();
            }));
        }
        private void Log(LogMsgType msgtype, string msg)
        {
            /*
                richTextBox1.Invoke(new EventHandler(delegate
                {
                int removeLine = richTextBox1.Lines.Length - Max_Showing_Message_Lines;
                if (removeLine > 0)
                {
                    int removeCount = 0;
                    for (int i = 0; i < removeLine; i++)
                    {
                        removeCount += richTextBox1.Lines[i].Length + 1; //計算行的字數和換行符號 
                    }
                    string temp = richTextBox1.Text.Remove(0, removeCount); //去除第一行和換行符號
                    temp += msg;
                    //richTextBox1.Text = ""; //清空 
                    //richTextBox1.AppendText(temp); //附加文字 ，其游標會自動再最後一行 
                    richTextBox1.Text = "";
                    richTextBox1.SelectedText = string.Empty;
                    richTextBox1.SelectionFont = new Font(richTextBox1.SelectionFont, FontStyle.Bold);
                    richTextBox1.SelectionColor = LogMsgTypeColor[(int)msgtype];
                    richTextBox1.AppendText(temp);
                }
                else
                {
                    richTextBox1.SelectedText = string.Empty;
                    richTextBox1.SelectionFont = new Font(richTextBox1.SelectionFont, FontStyle.Bold);
                    richTextBox1.SelectionColor = LogMsgTypeColor[(int)msgtype];
                    richTextBox1.AppendText(msg);
                }
                    richTextBox1.ScrollToCaret();
                }));
            */
                richTextBox1.Invoke(new EventHandler(delegate
                {
                    richTextBox1.SelectedText = string.Empty;
                    richTextBox1.SelectionFont = new Font(richTextBox1.SelectionFont, FontStyle.Bold);
                    richTextBox1.SelectionColor = LogMsgTypeColor[(int)msgtype];
                    richTextBox1.AppendText(msg);
                    richTextBox1.ScrollToCaret();
                }));
        }
        private void Log(string msg)
        {
            /*
            //if (richTextBox1.Lines.Length >= Max_Showing_Message_Lines)
                if (richTextBox1.Lines.Length >= 60)
                {

                richTextBox1.Invoke(new EventHandler(delegate
                {
                int removeLine = richTextBox1.Lines.Length - Max_Showing_Message_Lines;
                int removeCount = 0;
                for (int i = 0; i < removeLine; i++)
                {
                    removeCount += richTextBox1.Lines[i].Length + 1; //計算行的字數和換行符號 
                }
                string temp = richTextBox1.Text.Remove(0, removeCount); //去除第一行和換行符號
                temp += msg;
                //richTextBox1.Text = ""; //清空 
                //richTextBox1.AppendText(temp); //附加文字 ，其游標會自動再最後一行 
                    richTextBox1.Text = "";
                    richTextBox1.SelectedText = string.Empty;
                    richTextBox1.SelectionFont = new Font(richTextBox1.SelectionFont, FontStyle.Bold);
                    richTextBox1.SelectionColor = LogMsgTypeColor[(int)LogMsgType.Test];
                    richTextBox1.AppendText(temp);
                    richTextBox1.ScrollToCaret();
                }));
            }
            else
            {
                richTextBox1.Invoke(new EventHandler(delegate
                {
                    richTextBox1.SelectedText = string.Empty;
                    richTextBox1.SelectionFont = new Font(richTextBox1.SelectionFont, FontStyle.Bold);
                    richTextBox1.SelectionColor = LogMsgTypeColor[(int)LogMsgType.Test];
                    richTextBox1.AppendText(msg);
                    richTextBox1.ScrollToCaret();
                }));
            }
            */
                richTextBox1.Invoke(new EventHandler(delegate
                {
                    richTextBox1.SelectedText = string.Empty;
                    richTextBox1.SelectionFont = new Font(richTextBox1.SelectionFont, FontStyle.Bold);
                    richTextBox1.SelectionColor = LogMsgTypeColor[(int)LogMsgType.Test];
                    richTextBox1.AppendText(msg);
                    richTextBox1.ScrollToCaret();
                }));

        }
        public static DateTime PauseForMilliSeconds(int MilliSecondsToPauseFor)
        {


            System.DateTime ThisMoment = System.DateTime.Now;
            System.TimeSpan duration = new System.TimeSpan(0, 0, 0, 0, MilliSecondsToPauseFor);
            System.DateTime AfterWards = ThisMoment.Add(duration);


            while (AfterWards >= ThisMoment)
            {
                System.Windows.Forms.Application.DoEvents();
                ThisMoment = System.DateTime.Now;
            }


            return System.DateTime.Now;
        }
        private void btnOpenPort_Click(object sender, EventArgs e)
        {
            bool error = false;
            string filename;
            if (this.SavingLog_checkBox.Checked)
            {
                filename = Log_Name_textBox.Text.Trim();
                if (filename.Equals(String.Empty))
                {
                    MessageBox.Show(this, "Please input file name.", "error", MessageBoxButtons.OK);
                    return;
                }
            }
            else
            {
                filename = String.Empty;
            }

            try
            {
                // If the port is open, close it.
                if (gSerialComPort.IsOpen)
                {
                    Log(LogMsgType.Error, "Wait for Closing Serial Com Port.... " + Environment.NewLine);
                    gSerialComPort.DataReceived -= new SerialDataReceivedEventHandler(port_DataReceived);
                    if (ST_Monitor_Form != null && !ST_Monitor_Form.IsDisposed)
                    {
                        ST_Monitor_Form.Close();
                        ST_Monitor_Form.Dispose();
                    }

                    Application.DoEvents();
                    gSerialComPort.DiscardInBuffer();
                    gSerialComPort.DiscardOutBuffer();
                    PauseForMilliSeconds(1000);
                    Application.DoEvents();
                    gSerialComPort.Close();
                    Log(LogMsgType.Error, "Already Closed Serial Com Port." + Environment.NewLine);
                }
                else
                {
                    if (CurrentMonitorShowingSelect == MonitorShow.OneWireShowing)
                    {
                        ST_Monitor_Form = new LEV_ST_Monitor_Form(this, filename);
                        ST_Monitor_Form.Show();
                    }


                    gSerialComPort.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);

                    // Set the port's settings
                    gSerialComPort.BaudRate = int.Parse(cmbBaudRate.Text);
                    gSerialComPort.DataBits = int.Parse(cmbDataBits.Text);
                    gSerialComPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cmbStopBits.Text);
                    gSerialComPort.Parity = (Parity)Enum.Parse(typeof(Parity), cmbParity.Text);
                    gSerialComPort.PortName = GetSelectedComPortName();
                    //gSerialComPort.PortName =cmbPortName.Text;


                    // Open the port
                    gSerialComPort.Open();
                }

            }
            catch (UnauthorizedAccessException) { error = true; }
            catch (IOException) { error = true; }
            catch (ArgumentException) { error = true; }

                if (error)
                {
                    MessageBox.Show(this, "Could not open/close the COM port.  Most likely it is already in use, has been removed, or is unavailable.", "COM Port Unavalible", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                }
                else
                {
                    // Show the initial pin states
                    //UpdatePinState();
                    //chkDTR.Checked = comport.DtrEnable;
                    //chkRTS.Checked = comport.RtsEnable;
                }
            // Change the state of the form's controls
            EnableControls();
            if (gSerialComPort.IsOpen) btnOpenPort.Text = "&Close Port";
            else btnOpenPort.Text = "&Open Port";

            // If the port is open, send focus to the send data box
            if (gSerialComPort.IsOpen)
            {
                //txtSendData.Focus();
                //if (chkClearOnOpen.Checked) ClearTerminal();
            }
        }


        private void SerialPortForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            bool error = false;
            // The form is closing, save the user's preferences
            SaveSettings();
            Log(LogMsgType.Error, "Wait for Closing Serial Com Port.... " + Environment.NewLine);
            gSerialComPort.DataReceived -= new SerialDataReceivedEventHandler(port_DataReceived);
            if (ST_Monitor_Form != null && !ST_Monitor_Form.IsDisposed)
            {
                ST_Monitor_Form.Close();
                ST_Monitor_Form.Dispose();
            }
            try
            {
                if (gSerialComPort.IsOpen)
                {
                    Application.DoEvents();
                    gSerialComPort.DiscardInBuffer();
                    gSerialComPort.DiscardOutBuffer();
                    PauseForMilliSeconds(1000);
                    Application.DoEvents();
                    gSerialComPort.Close();
                }
                Log(LogMsgType.Error, "Already Closed Serial Com Port." + Environment.NewLine);


            }
            catch (UnauthorizedAccessException) { error = true; }
            catch (IOException) { error = true; }
            catch (ArgumentException) { error = true; }

            if (error)
            {
                MessageBox.Show(this, "Could not open/close the COM port.  Most likely it is already in use, has been removed, or is unavailable.", "COM Port Unavalible", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
            else
            {

            }
        }

        private void CheckCRC_button_Click(object sender, EventArgs e)
        {
            byte[] tempbuffer1 = ReceivedComPortBytesList.ToArray<Byte>();
            byte[] tempbuffer2 = TrasnmitComPortBytesList.ToArray<Byte>();
            byte[] tempbuffer = new byte[2];

            int matchIndex = 0;
            // remove ecoh
            if (CurrentDataConnection == connection.Half_Duplex)
            {
                if (tempbuffer1.Length > tempbuffer2.Length)
                {
                    for (int i = 0; i < tempbuffer2.Length; i++)
                    {
                        if (tempbuffer2[i] == tempbuffer1[i])
                        {
                            matchIndex++;
                        }
                    }
                    if (matchIndex == tempbuffer2.Length)
                    {
                        tempbuffer = new byte[tempbuffer1.Length - tempbuffer2.Length];
                        Array.Copy(tempbuffer1, tempbuffer2.Length, tempbuffer, 0, tempbuffer.Length);
                    }
                }
            }


            byte[] CheckCRCbuffer = new byte[tempbuffer.Length - 2];
            Array.Copy(tempbuffer, 0, CheckCRCbuffer, 0, CheckCRCbuffer.Length);
            ushort receiveCRC = (ushort)((tempbuffer[tempbuffer.Length - 2] << 8) + tempbuffer[tempbuffer.Length - 1]);
            ushort crc = ModbusCRC16.ComputeCrc(CheckCRCbuffer);
            bool crcCheck = false;
            if (crc == receiveCRC)
            {
                crcCheck = true;
            }
            // Show the user the incoming data in hex format
            Log(LogMsgType.Incoming, ByteArrayToHexString(tempbuffer));
            Log(LogMsgType.Incoming, "{receive with crc bytes: " + tempbuffer.Length + ", CRC = " + crcCheck + "}" + Environment.NewLine);
            ReceivedComPortBytesList.Clear();
            TrasnmitComPortBytesList.Clear();

        }


        //List<Byte> tempList = new List<Byte>();
        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            bool StFlag = false;
            int StIndex;
            bool EndFlag = false;
            int EndIndex;
            StIndex = 0;
            EndIndex = 0;
            // If the com port has been closed, do nothing
            if (!gSerialComPort.IsOpen) return;

            // This method will be called when there is data waiting in the port's buffer

            // Determain which mode (string or binary) the user is in
            if (CurrentDataMode == DataMode.Text)
            {
                // Read all the data waiting in the buffer
                string data = gSerialComPort.ReadExisting();

                // Display the text to the user in the terminal
                Log(LogMsgType.Incoming, data);
            }
            else
            {
                // Obtain the number of bytes waiting in the port's buffer
                int readbytes = gSerialComPort.BytesToRead;
                if (readbytes > 0)
                {
                    // Create a byte array buffer to hold the incoming data
                    byte[] buffer = new byte[readbytes];
                    // Read the data from the port and store it in our buffer
                    gSerialComPort.Read(buffer, 0, readbytes);

                    if (this.Show_Communication_Messages_checkBox.Checked)
                    {
                        Log(LogMsgType.Test, "RAW Data: " + ByteArrayToHexString(buffer));
                    }
                    Log(LogMsgType.Test, "{receive bytes: " + buffer.Length + "}" + Environment.NewLine);
                    //return;
                    ReceivedComPortBytesList.AddRange(buffer);
                    if (CurrentMonitorShowingSelect == MonitorShow.OneWireShowing)
                    {
                        //add hsinmo
                        List<List<byte>> outDataList;
                        List<List<byte>> outEEPROMList;
                        checkBufferString(ref ReceivedComPortBytesList, out outDataList, out outEEPROMList);
                        foreach (List<byte> list in outDataList)
                        {
                            byte[] tempbuffer = list.ToArray<Byte>();
                            byte[] CheckCRCbuffer = new byte[tempbuffer.Length - 2];
                            Array.Copy(tempbuffer, 0, CheckCRCbuffer, 0, CheckCRCbuffer.Length);
                            ushort receiveCRC = (ushort)((tempbuffer[tempbuffer.Length - 2] << 8) + tempbuffer[tempbuffer.Length - 1]);
                            ushort crc = ModbusCRC16.ComputeCrc(CheckCRCbuffer);
                            bool crcCheck = false;
                            if (crc == receiveCRC)
                            {
                                crcCheck = true;
                                if (!ST_Monitor_Form.IsDisposed)
                                {
                                    ST_Monitor_Form.set_Sys_Status(CheckCRCbuffer);
                                    //ST_Monitor_Form.Set_All_Indication_Values(CheckCRCbuffer);
                                }
                            }
                            // Show the user the incoming data in hex format
                            if (this.Show_Communication_Messages_checkBox.Checked)
                            {
                                Log(LogMsgType.Incoming, ByteArrayToHexString(tempbuffer) + "{receive with crc bytes: " + tempbuffer.Length + ", CRC = " + crcCheck + "}" + Environment.NewLine + Environment.NewLine);
                            }
                            Log(LogMsgType.Incoming, "{receive with crc bytes: " + tempbuffer.Length + ", CRC = " + crcCheck + "}" + Environment.NewLine + Environment.NewLine);
                        }
                        foreach (List<byte> list in outEEPROMList)
                        {
                            byte[] tempbuffer = list.ToArray<Byte>();
                            byte[] CheckCRCbuffer = new byte[tempbuffer.Length - 2];
                            Array.Copy(tempbuffer, 0, CheckCRCbuffer, 0, CheckCRCbuffer.Length);
                            ushort receiveCRC = (ushort)((tempbuffer[tempbuffer.Length - 2] << 8) + tempbuffer[tempbuffer.Length - 1]);
                            ushort crc = ModbusCRC16.ComputeCrc(CheckCRCbuffer);
                            bool crcCheck = false;
                            if (crc == receiveCRC)
                            {
                                crcCheck = true;
                                if (!ST_Monitor_Form.IsDisposed)
                                {
                                    //ST_Monitor_Form.set_Sys_Status(CheckCRCbuffer);
                                    ST_Monitor_Form.Set_Flash_Values(CheckCRCbuffer);
                                }
                            }
                            // Show the user the incoming data in hex format
                            if (this.Show_Communication_Messages_checkBox.Checked)
                            {
                                Log(LogMsgType.Incoming, ByteArrayToHexString(tempbuffer) + "{receive with crc bytes: " + tempbuffer.Length + ", CRC = " + crcCheck + "}" + Environment.NewLine + Environment.NewLine);
                            }
                            Log(LogMsgType.Incoming, "{receive with crc bytes: " + tempbuffer.Length + ", CRC = " + crcCheck + "}" + Environment.NewLine + Environment.NewLine);
                        }
                    }
                    else
                    {



                    }
                    return;

                }
            }
        }

        const byte CheckBytesNumbers = 4;
        const byte St0 = 0x80;
        const byte St1 = 0xf8;
        const byte St2 = 0x80;
        const byte Data_Code = 0xA0;
        const byte Flash_Code = 0xD0;

        const byte End0 = 0x70;
        const byte End1 = 0xf7;
        const byte End2 = 0x70;
        const byte End3 = 0xf7;
        void checkBufferString(ref List<byte> orgList, out List<List<byte>> resultList, out List<List<byte>> resultEEPROMList)
        {
            bool StFlag = false;
            int StIndex;
            bool EndFlag = false;
            int EndIndex;
            StIndex = 0;
            EndIndex = 0;

            bool DataFlag = false;
            bool EepromFlag = false;

            resultList = new List<List<byte>>();
            resultEEPROMList = new List<List<byte>>();


            byte[] tempbuffer = orgList.ToArray<Byte>();
            int length = tempbuffer.Length;
            for (int i = 0; i < length; i++)
            {
                if (tempbuffer[i] == St0)
                {
                    if (((i + 1) < length) && (tempbuffer[i + 1] == St1) &&
                        ((i + 2) < length) && (tempbuffer[i + 2] == St2))
                    //if (((i + 1) < length) && (tempbuffer[i + 1] == St1) &&
                        //((i + 2) < length) && (tempbuffer[i + 2] == St2) &&
                        //((i + 3) < length) && (tempbuffer[i + 3] == St3))
                    {
                        StFlag = true;
                        StIndex = i;
                        if ((i + 3) < length)
                        {
                            if (tempbuffer[i + 3] == Data_Code)
                            {
                                DataFlag = true;
                            }
                            else if ((tempbuffer[i + 3] & 0xf0) == Flash_Code)
                            {
                                EepromFlag = true;
                            }
                        }
                    }
                }
                if (StFlag && (tempbuffer[i] == End0))
                {
                    if (((i + 1) < length) && (tempbuffer[i + 1] == End1) &&
                        ((i + 2) < length) && (tempbuffer[i + 2] == End2) &&
                        ((i + 3) < length) && (tempbuffer[i + 3] == End3))
                    {
                        EndFlag = true;
                        EndIndex = i + 4;
                    }
                }//if (StFlag && (buffer[i] == End0))
                if (StFlag && EndFlag)
                {
                    byte[] resultbuffer = new byte[EndIndex - StIndex - CheckBytesNumbers - CheckBytesNumbers];
                    //checking code remove and save receive data
                    Array.Copy(tempbuffer, StIndex + CheckBytesNumbers, resultbuffer, 0, EndIndex - StIndex - CheckBytesNumbers - CheckBytesNumbers);
                    List<byte> innerList = new List<Byte>();
                    innerList.AddRange(resultbuffer);
                    //resultList = new List<List<byte>>();
                    if (DataFlag)
                    {
                        resultList.Add(innerList);
                    }
                    else if (EepromFlag)
                    {
                        resultEEPROMList.Add(innerList);
                    }

                    byte[] remainbuffer = new byte[tempbuffer.Length - EndIndex];
                    Array.Copy(tempbuffer, EndIndex, remainbuffer, 0, remainbuffer.Length);
                    orgList.Clear();
                    orgList.AddRange(remainbuffer);
                    StFlag = false;
                    EndFlag = false;
                    DataFlag = false;
                    EepromFlag = false;
                }

            }//for (int i = 0; i < length; i++)

        }
        /// <summary>
        /// /////////////////////////////////////////////////////////////////
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private SerialPort test_comport;
        private Boolean test_sending;

        private void startSending_button_Click(object sender, EventArgs e)
        {

            bool error = false;
            test_comport = new SerialPort();
            test_sending = false;
                // Set the port's settings
            test_comport.BaudRate = int.Parse(cmbBaudRate.Text);
            test_comport.DataBits = int.Parse(cmbDataBits.Text);
            test_comport.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cmbStopBits.Text);
            test_comport.Parity = (Parity)Enum.Parse(typeof(Parity), cmbParity.Text);
            test_comport.PortName = GetSelectedComPortName();

            try
            {
                // Open the port
                test_comport.Open();
                Log("open port");
            }
            catch (UnauthorizedAccessException) { error = true; }
            catch (IOException) { error = true; }
            catch (ArgumentException) { error = true; }

            if (error)
            {
                MessageBox.Show(this, "Could not open the COM port.  Most likely it is already in use, has been removed, or is unavailable.", "COM Port Unavalible", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
            else
            {
                startSending_button.Enabled = false;

                if (!test_sending)
                {
                    Log("start Thread");
                    Thread t = new Thread(SendData);
                    t.IsBackground = true;
                    t.Start(test_comport as Object);
                }


            }

        }

        private void CloseTestComport(SerialPort port)
        {
            test_sending = false;
            Thread.Sleep(500);//500 ms
            try
            {
                if ((test_comport != null) && (test_comport.IsOpen) && (!test_sending))
                {
                    test_comport.Close();
                    MessageBox.Show("序列埠已關閉");
                }
            }
            catch (Exception ex)
            {
                //這邊你可以自訂發生例外的處理程序
                MessageBox.Show(String.Format("出問題啦:{0}", ex.ToString()));
            }

        }
        private void SendData(Object port)
        {
            Byte[] buffer = new Byte[512];
            for (int i = 0; i < 512; i++)
            {
                buffer[i] = (Byte)(i % 256);
            }
            buffer[1] = 0x80;
            buffer[2] = 0xf8;
            buffer[3] = 0xf8;
            buffer[4] = 0xf8;

            buffer[508] = 0x70;
            buffer[509] = 0xf7;
            buffer[510] = 0xf7;
            buffer[511] = 0xf7;

            /*
            buffer[1] = 0x70;
            buffer[2] = 0xf7;
            buffer[3] = 0xf7;
            buffer[4] = 0xf7;

            buffer[508] = 0x80;
            buffer[509] = 0xf8;
            buffer[510] = 0xf8;
            buffer[511] = 0xf8;
            */

            test_sending = true;
            try
            {
                while (test_sending)
                {
                    Log("SendData");
                    (port as SerialPort).Write(buffer, 0, buffer.Length);
                    Thread.Sleep(500);//500 ms
                }
            }
            catch (Exception ex)
            {
                //這邊你可以自訂發生例外的處理程序
                CloseTestComport((port as SerialPort));
                MessageBox.Show(String.Format("出問題啦:{0}", ex.ToString()));
            }
            finally
            {
                test_sending = false;
            }

        }

        private void stopSending_button_Click(object sender, EventArgs e)
        {
            CloseTestComport(test_comport);
            startSending_button.Enabled = true;

        }

        private void show_form_button1_Click(object sender, EventArgs e)
        {
            LEV_ST_Monitor_Form f = new LEV_ST_Monitor_Form(this, "");
            f.Show();
        }
        /// <summary> Send the user's data currently entered in the 'send' box.</summary>
        private void SendingData_with_CRC16(bool SendWithCRCBytesFlag, bool SendWithLeadingCodeFlag)
        {

            try
            {
                // Convert the user's string of hex digits (ex: B4 CA E2) to a byte array
                byte[] pre_data = HexStringToByteArray(sendData_textBox.Text);
                byte[] address = HexStringToByteArray(this.Slave_Address_textBox.Text);
                byte[] data;
                byte[] sendingData;

                if (SendWithCRCBytesFlag)
                {
                    //CRC check
                    UInt16 crc = ModbusCRC16.ComputeCrc(pre_data);
                    data = new byte[pre_data.Length + 2];

                    pre_data.CopyTo(data, 0);
                    data[pre_data.Length] = (byte)(crc >> 8);    // high byte
                    data[pre_data.Length + 1] = (byte)crc;    //low byte
                }
                else
                {
                    data = new byte[pre_data.Length];
                    pre_data.CopyTo(data, 0);
                }

                if (SendWithLeadingCodeFlag)
                {
                    sendingData = new byte[data.Length + 4];
                    data.CopyTo(sendingData, 2);
                    sendingData[0] = 0x3A;
                    sendingData[1] = address[0];
                    sendingData[sendingData.Length - 2] = 0x0D;
                    sendingData[sendingData.Length - 1] = 0x0A;
                }
                else
                {
                    sendingData = new byte[data.Length];
                    data.CopyTo(sendingData, 0);
                }
                // Send the binary data out the port
                gSerialComPort.Write(sendingData, 0, sendingData.Length);

                TrasnmitComPortBytesList.AddRange(sendingData);
                // Show the hex digits on in the terminal window
                Log(LogMsgType.Normal, "Send Data : " + ByteArrayToHexString(sendingData) + "\n");

            }
            //catch (FormatException)
            catch (Exception ex)
            {
                // Inform the user if the hex string was not properly formatted
                //Log(LogMsgType.Error, "Not properly formatted hex string: " + sendData_textBox.Text + "\n");
                Log(LogMsgType.Error, "Error: " + ex.ToString() + "\n");
            }
            //sendData_textBox.SelectAll();
        }//private void SendingData_with_CRC16(bool SendWithCRCBytesFlag, bool SendWithLeadingCodeFlag)

        private void SendingData_with_CheckSum16(bool SendWithCKSBytesFlag, bool SendWithLeadingCodeFlag)
        {

            try
            {
                // Convert the user's string of hex digits (ex: B4 CA E2) to a byte array
                byte[] pre_data = HexStringToByteArray(sendData_textBox.Text);
                byte[] address = HexStringToByteArray(this.Slave_Address_textBox.Text);
                byte[] data;
                byte[] sendingData;

                if (SendWithCKSBytesFlag)
                {
                    //CheckSum check
                    UInt16 CheckSum = ModbusCRC16.ComputeCheckSum(pre_data);
                    CheckSum += address[0];
                    data = new byte[pre_data.Length + 2];

                    pre_data.CopyTo(data, 0);
                    data[pre_data.Length] = (byte)(CheckSum);    // low byte
                    data[pre_data.Length + 1] = (byte)(CheckSum >> 8);    //high byte
                }
                else
                {
                    data = new byte[pre_data.Length];
                    pre_data.CopyTo(data, 0);
                }

                if (SendWithLeadingCodeFlag)
                {
                    sendingData = new byte[data.Length + 4];
                    data.CopyTo(sendingData, 2);
                    sendingData[0] = 0x3A;
                    sendingData[1] = address[0];
                    sendingData[sendingData.Length - 2] = 0x0D;
                    sendingData[sendingData.Length - 1] = 0x0A;
                }
                else
                {
                    sendingData = new byte[data.Length];
                    data.CopyTo(sendingData, 0);
                }
                // Send the binary data out the port
                gSerialComPort.Write(sendingData, 0, sendingData.Length);

                TrasnmitComPortBytesList.AddRange(sendingData);
                // Show the hex digits on in the terminal window
                Log(LogMsgType.Normal, "Send Data : " + ByteArrayToHexString(sendingData) + "\n");

            }
            //catch (FormatException)
            catch (Exception ex)
            {
                // Inform the user if the hex string was not properly formatted
                //Log(LogMsgType.Error, "Not properly formatted hex string: " + sendData_textBox.Text + "\n");
                Log(LogMsgType.Error, "Error: " + ex.ToString() + "\n");
            }
            //sendData_textBox.SelectAll();
        }//private void SendingData_with_CheckSum16(bool SendWithCKSBytesFlag, bool SendWithLeadingCodeFlag)
        private void SendDataByInputText()
        {
            if (gSerialComPort.IsOpen)
            {
                if (this.calculate_CRC16_radioButton.Checked)
                {
                    SendingData_with_CRC16(true, LeadingCodes_checkBox.Checked);
                }
                else if (this.calculate_CheckSum16_radioButton.Checked)
                {
                    SendingData_with_CheckSum16(true, LeadingCodes_checkBox.Checked);
                }
                else
                {
                    SendingData_with_CRC16(false, LeadingCodes_checkBox.Checked);
                }
            }
            else
            {
                // Inform the user if the hex string was not properly formatted
                Log(LogMsgType.Error, "SerialComPor is not opened : " + sendData_textBox.Text + "\n");
            }
        }
        private void SendData_button_Click(object sender, EventArgs e)
        {
            SendDataByInputText();
        }
        private void sendData_textBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                SendDataByInputText();
                //Button1_Click(sender, e);
            }
        }

        private void Clear_messages_button_Click(object sender, EventArgs e)
        {
            Log_Clear();
        }

        private void SavingLog_checkBox_CheckedChanged(object sender, EventArgs e)
        {
            if (SavingLog_checkBox.Checked)
            {
                Log_Name_textBox.Enabled = true;
            }
            else
            {
                Log_Name_textBox.Enabled = false;
            }
        }

        private int test_message_count;
        private void Set_messages_button_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 8; i++)
            {
                Log(LogMsgType.Incoming, "Test Message: " + test_message_count + Environment.NewLine);
                test_message_count++;

            }
        }

        private void richTextBox1_VScroll(object sender, EventArgs e)
        {
            return;

            int msgtype = 0;
            string msg = string.Empty;
                int removeLine = richTextBox1.Lines.Length - Max_Showing_Message_Lines;
                if (removeLine > 0)
                {
                    int removeCount = 0;
                    for (int i = 0; i < removeLine; i++)
                    {
                        removeCount += richTextBox1.Lines[i].Length + 1; //計算行的字數和換行符號 
                    }
                    string temp = richTextBox1.Text.Remove(0, removeCount); //去除多出的行和換行符號
                    temp += msg;
                    //richTextBox1.Text = ""; //清空 
                    //richTextBox1.AppendText(temp); //附加文字 ，其游標會自動再最後一行 
                    richTextBox1.Text = "";
                    richTextBox1.SelectedText = string.Empty;
                    richTextBox1.SelectionFont = new Font(richTextBox1.SelectionFont, FontStyle.Bold);
                    richTextBox1.SelectionColor = LogMsgTypeColor[(int)msgtype];
                    richTextBox1.AppendText(temp);
                }
                else
                {
                    richTextBox1.SelectedText = string.Empty;
                    richTextBox1.SelectionFont = new Font(richTextBox1.SelectionFont, FontStyle.Bold);
                    richTextBox1.SelectionColor = LogMsgTypeColor[(int)msgtype];
                    richTextBox1.AppendText(msg);
                }
                richTextBox1.ScrollToCaret();
        }

        private void PortScan_button_Click(object sender, EventArgs e)
        {
            string[] PortArray = UpdatedComPortAndDescription();
            //gSerialComPort
            if(!gSerialComPort.IsOpen){
                Log(LogMsgType.Incoming, " gSerialComPort = Null" + Environment.NewLine);
            }else{
                //Log(LogMsgType.Incoming, " gSerialComPort Opne " + gSerialComPort.CDHolding + Environment.NewLine);
            }


            
            for (int i = 0; i < PortArray.GetLength(0); i++)
            {

                Log(LogMsgType.Incoming, PortArray[i] + " " + " " + Environment.NewLine);
            }
            Log(LogMsgType.Incoming, " " + Environment.NewLine);

        }

        private void cmbPortName_MouseClick(object sender, MouseEventArgs e)
        {
            string[] PortArray = UpdatedComPortAndDescription();
            cmbPortName.Items.Clear();
            cmbPortName.Items.AddRange(PortArray);
            bool cmbPortNameSelected = false;
            for (int i = 0; i < PortArray.GetLength(0); i++)
            {
                cmbPortName.SelectedIndex = i;
                if (cmbPortName.Text.Contains(settings.PortName))
                {
                    cmbPortNameSelected = true;
                    break;
                }
            }
            if (!cmbPortNameSelected)
            {
                //cmbPortName.SelectedIndex = 0;
            }
        
        }

        private void Generic_button_Click(object sender, EventArgs e)
        {

        }

        private void Open_FA_Data_Log_button_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            //openFileDialog.InitialDirectory = @"C:\";

            if (System.IO.Directory.Exists(FA_Tool_Default_Director))
            {
                openFileDialog.InitialDirectory = FA_Tool_Default_Director;
            }
            else
            {
                //openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);//我的文件folder
                openFileDialog.InitialDirectory = Data_Log_Directory;//我的文件folder
                //openFileDialog.InitialDirectory = System.Windows.Forms.Application.StartupPath;//目前程式路徑
            }
            openFileDialog.Filter = "文字檔|*.txt|所有文件|*.*";
            openFileDialog.RestoreDirectory = true;
            openFileDialog.FilterIndex = 1;

            string fName;
            byte[] SystemData;
            byte[] EEpromData;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                fName = openFileDialog.FileName;
                Log(LogMsgType.Normal, "Log File opened : " + fName + "\n");

                if (Parsing_FA_Tool_DataLog(fName, out SystemData, out EEpromData))
                {
                    LEV_ST_Monitor_Form FA_Log = new LEV_ST_Monitor_Form(this, "");
                    FA_Log.Show();
                    FA_Log.Set_SaveLog_FileName(fName);
                    //FA_Log.Text = "FA Tool Data Log : " + fName;
                    FA_Log.set_Sys_Status(SystemData);
                    FA_Log.Set_Flash_Values(EEpromData);
                }
                else
                {
                    Log(LogMsgType.Error, "Log File Format Error : " + fName + "\n");
                }

            }　

        }
        private bool Parsing_FA_Tool_DataLog(string fa_dataLogName, out byte[] SystemData, out byte[] EEpromData)
        {
            //StreamReader FA_Tool_DataLogReader;
            string str;
            bool Result = false;
            SystemData = new byte[0];
            EEpromData = new byte[0];
            try
            {
                FileStream fsFile = new FileStream(fa_dataLogName, FileMode.Open);
                /*
                 * 讀取數據最簡單的方法是Read()。此方法將流的下一個字符作為正整數值返回，
                 * 如果達到了流的結尾處，則返回-1。
                 */
                FA_Tool_DataLogReader = new StreamReader(fsFile, Encoding.Default);
                ////////////////////////////////////////////////////////////////////////
                //Continue to read until you reach end of file
                //Find Start Address
                int dataEndCount = 0;
                bool StartGetData = false;
                string wholeDataString = "";
                while (FA_Tool_DataLogReader.Peek() >= 0)
                {
                    str = FA_Tool_DataLogReader.ReadLine();
                    str = HM_Utilitys.StringTrim_Replace_EnterAndTab_CombineMultiSpaceToOne(str);
                    if (!StartGetData && (str.IndexOf(FA_Tool_Log_Detection_Tick) >= 0))
                    {
                        //Log(LogMsgType.Normal, str + "\n");
                        StartGetData = true;
                    }
                    if (StartGetData)
                    {
                        wholeDataString += str;
                        if (str.IndexOf(';') >= 0)
                        {
                            dataEndCount++;
                        }
                        if (dataEndCount >= 3)//已經找到三個';'號，資料已取得。
                        {
                            Result = true;
                            StartGetData = false;
                            Log(LogMsgType.Normal, wholeDataString + "\n");
                            string[] strArr;
                            strArr = wholeDataString.Split(new char[] { ';' });
                            SystemData = HM_Utilitys.HexStringToByteArray(strArr[1]);
                            EEpromData = HM_Utilitys.HexStringToByteArray(strArr[2]);
                            break;
                        }
                    }
                }//while()

            }
            catch (Exception excep)
            {
                //Console.WriteLine("檔案開啟錯誤 : " + strPathFileName);
                //Console.WriteLine("  : " + excep);
                if (FA_Tool_DataLogReader != null)
                {
                    FA_Tool_DataLogReader.Close();
                }
                //throw excep;
            }
            finally
            {
                if (FA_Tool_DataLogReader != null)
                {
                    FA_Tool_DataLogReader.Close();
                }
            }
            return Result;
        }


        private void logMessage(string str)
        {
            Log(LogMsgType.Normal, str + "\n");
        }
        private void button1_Click(object sender, EventArgs e)
        {
            LEV_D2_DataFormatParsingClass ld = new LEV_D2_DataFormatParsingClass(logMessage);
        }

        private void SerialPortForm_Load(object sender, EventArgs e)
        {
            this.Log(LogMsgType.Normal, "[Application Program Directory] " + Environment.NewLine);
            this.Log(LogMsgType.Incoming, Environment.CurrentDirectory + Environment.NewLine);
            this.Log(LogMsgType.Normal, "[MyDocuments Directory] " + Environment.NewLine);
            this.Log(LogMsgType.Incoming, Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + Environment.NewLine);

            Data_Log_Directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), Data_Log_Default_Folder);
            this.Log(LogMsgType.Normal, "[Data Log Storing Directory] (to MyDocuments) " + Environment.NewLine);
            this.Log(LogMsgType.Incoming, Data_Log_Directory + Environment.NewLine);
            if (!System.IO.Directory.Exists(Data_Log_Directory))
            {
                //System.IO.Directory.CreateDirectory(Data_Log_Directory);
            }

            FileStream fsFile = new FileStream("Test_Save_File" + ".CSV", FileMode.Create);
            StreamWriter TestSaveFileStream = new StreamWriter(fsFile, Encoding.Default);  //使用與系統一致的碼方式
            // Add some text to the file.
            TestSaveFileStream.WriteLine("----------------------------------");
            TestSaveFileStream.WriteLine("This is the header for the file.");
            TestSaveFileStream.WriteLine("The File Name: " + fsFile.Name);
            TestSaveFileStream.Write("The date is: ");
            TestSaveFileStream.WriteLine(DateTime.Now);
            TestSaveFileStream.WriteLine("----------------------------------");
            TestSaveFileStream.Close();
            fsFile.Close();
        }

        /// /////////////////////////////////////////////////////////////////

    }//class
    /*
    /// <summary>
    /// 动态数据类型
    /// </summary>
    public class DynamicValue
    {
        public string DataType { get; protected set; }

        /// <summary>
        /// 获取值之泛型方法
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <returns>
        /// 值
        /// </returns>
        public T GetValue<T>()
        {
            if (DataType == typeof(T).ToString())
            {
                return ((DynamicValue<T>)this).Value;
            }
            return default(T);
        }

        /// <summary>
        /// 设置值之泛型方法
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="value">待复制参数</param>
        /// <returns>
        /// false:设置失败
        /// true:设置成功
        /// </returns>
        public bool SetValue<T>(T value)
        {
            if (DataType == typeof(T).ToString())
            {
                ((DynamicValue<T>)this).Value = value;
                return true;
            }
            return false;
        }

    }



    /// <summary>
    /// 动态数据类型之泛型类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class DynamicValue<T> : DynamicValue
    {
        /// <summary>
        /// 保存值
        /// </summary>
        public T Value { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public DynamicValue()
            : this(default(T))
        {
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="value"></param>
        public DynamicValue(T value)
        {
            Value = value;
            DataType = typeof(T).ToString();
        }
     }
        */
}

